// pvccupload.cpp : Defines the entry point for the console application.
//


#include "stdafx.h"

#define TRUE 1
#define FALSE 0
#define FILE_ERROR 0

#define NO_POWER_FOUND 2

#define DATE_FOUND 4
#define TIME_FOUND 5
#define POWER_FOUND 6
#define BACK_IN_TIME_5 (5 * 60)
#define BACK_IN_TIME_10 (10 * 60)

#define DATE_NOT_FOUND -1
#define TIME_NOT_FOUND -2
#define POWER_NOT_FOUND -3
#define FILE_NOT_FOUND -4
#define NEW_PROCESS_FAILED -5

#define FORMULA_CC_GREATER_THAN_UPPER_LIMIT 0
#define FORMULA_SE_POWER_0 1
#define FORMULA_POWER_APPROX_EQUAL 2
#define FORMULA_CC_GREATER_THAN_SE 3
#define FORMULA_DEFAULT 4
#define FORMULA_SE_GREATER_THAN_CC 5
#define FORMULA_SE_AT_UPPER_LIMIT 6
#define FORMULA_SE_GREATER_THAN_CC_SUBTRACTIVE 7
#define FORMULA_SE_GREATER_THAN_CC_ADDITIVE 8
#define FORMULA_SE_GREATER_THAN_CC_ADAPTIVE 9
#define FORMULA_RAW_CC_POWER 10


static char formula_list[20][80];
static int receive_count = 0;
static int watts_5_min_interval_count = 0;
static int watts_5_min_average;
static int watts_sub_total = 0;
static int in_session = FALSE;
static FILE *fpLog;

static char api_key[80];
static char system_id[10];
static char plant_name[MAX_PATH];
static char cc_file_name[MAX_PATH];
static char archive_dir[MAX_PATH];

static char se_input_path[MAX_PATH];
static char se_output_path[MAX_PATH];
static char back_date[20];
static char back_date_start[80];
static char back_time_start[80];
static char my_lat[80];
static char my_long[80];
static char my_tz[80];
static char use_power_calculations[4];


static char init_file_name[] = "pvccupload.ini";
static FILE *pfinit;

static int se_upper_limit_power = 4000;
static int standby_power = 600;
static int power_difference = 100;
static int formula_used = 0;
static int sundown = FALSE;
static int sunrise_hour = 0;
static int sunrise_minute = 0;
static int sunset_hour = 0;
static int sunset_minute = 0;
static double cc_power_adjustment = 0.0;

double pi = 3.14159;
double degs;
double rads;

double L,g,daylen;
double SunDia = 0.53;     // Sunradius degrees
double AirRefr = 34.0/60.0; // athmospheric refraction degrees //




/* CODE START HERE */
/*void get_args(int argc, char** argv, int* a_value, float* b_value)
{
    int i;

   
    for (i = 1; i < argc; i++) {

	

	if (argv[i][0] == '-') {

	   

	    switch (argv[i][1]) {

		case 'a':	*a_value = atoi(argv[++i]);
				break;

		case 'b':	*b_value = atof(argv[++i]);
				break;

		default:	fprintf(stderr,
				"Unknown switch %s\n", argv[i]);
	    }
	}
    }
}*/


void print_time(void)
{
	time_t tim;
	struct tm *now;
	char *my_time;
	char s_my_time[80];
	int size;

	time(&tim);
	now=localtime(&tim);
	my_time = asctime(now);
	size = strlen(my_time);
	my_time[size - 1] = '\0';
	strcpy(s_my_time,my_time);
	fprintf(fpLog,"%s: ",s_my_time);
	fflush(fpLog);
}

	
void init_formula_list()
{
	
	strcpy(formula_list[FORMULA_CC_GREATER_THAN_UPPER_LIMIT],"Power Formula Used: CC GREATER THAN UPPER LIMIT");
	strcpy(formula_list[FORMULA_SE_POWER_0],"Power Formula Used: SE POWER IS ZERO");
	strcpy(formula_list[FORMULA_POWER_APPROX_EQUAL],"Power Formula Used: APPROX EQUAL");
	strcpy(formula_list[FORMULA_CC_GREATER_THAN_SE],"Power Formula Used: CC GREATER THAN SE");
	strcpy(formula_list[FORMULA_SE_GREATER_THAN_CC],"Power Formula Used: SE GREATER THAN CC");
	strcpy(formula_list[FORMULA_SE_AT_UPPER_LIMIT],"Power Formula Used: SE AT UPPER LIMIT");
	strcpy(formula_list[FORMULA_DEFAULT],"Power Formula Used: DEFAULT");
	strcpy(formula_list[FORMULA_SE_GREATER_THAN_CC_SUBTRACTIVE],"Power Formula Used: SE GREATER THAN CC (SUBTRACTIVE)");
	strcpy(formula_list[FORMULA_SE_GREATER_THAN_CC_ADDITIVE],"Power Formula Used: SE GREATER THAN CC (ADDITIVE)");
	strcpy(formula_list[FORMULA_SE_GREATER_THAN_CC_ADAPTIVE],"Power Formula Used: SE GREATER THAN CC (ADAPTIVE)");
	strcpy(formula_list[FORMULA_RAW_CC_POWER],"Power Formula Used: RAW CC POWER (NO CALCULATIONS APPLIED");
}

int init_params()
{
	char buffer[180];
	errno = 0;
	char *token;
	int return_status = TRUE;

	pfinit = fopen(init_file_name,"r");
	if (pfinit == NULL)
	{
		fprintf (fpLog,"Error opening INIT File - %s - %s\n",init_file_name,strerror(errno));
		fflush(fpLog);
		return FALSE;
	}
	fgets(buffer,sizeof (buffer),pfinit);
	token = strtok(buffer,";");
	if(token != NULL)
	{
		strcpy(api_key,token);
	}else{
		return_status = FALSE;
	}
	
	fgets(buffer,sizeof (buffer),pfinit);
	token = strtok(buffer,";");
	if(token != NULL)
	{
		strcpy(system_id,token);
	}else{
		return_status = FALSE;
	}
	
	
	fgets(buffer,sizeof (buffer),pfinit);
	token = strtok(buffer,";");
	if(token != NULL)
	{
		strcpy(plant_name,token);
	}else{
		return_status = FALSE;
	}
	
	
	fgets(buffer,sizeof (buffer),pfinit);
	token = strtok(buffer,";");
	if(token != NULL)
	{
		strcpy(cc_file_name,token);
	}else{
		return_status = FALSE;
	}
		
	fgets(buffer,sizeof (buffer),pfinit);
	token = strtok(buffer,";");
	if(token != NULL)
	{
		power_difference = atoi(token);
	}else{
		return_status = FALSE;
	}
	

	fgets(buffer,sizeof (buffer),pfinit);
	token = strtok(buffer,";");
	if(token != NULL)
	{
		standby_power = atoi(token);	
	}else{
		return_status = FALSE;
	}
	
	
	fgets(buffer,sizeof (buffer),pfinit);
	token = strtok(buffer,";");
	if(token != NULL)
	{
		strcpy(se_input_path,token);
	}else{
		return_status = FALSE;
	}
		
	fgets(buffer,sizeof (buffer),pfinit);
	token = strtok(buffer,";");
	if(token != NULL)
	{
		strcpy(back_date,token);
	}else{
		return_status = FALSE;
	}

	fgets(buffer,sizeof (buffer),pfinit);
	token = strtok(buffer,";");
	if(token != NULL)
	{
		strcpy(back_date_start,token);
	}else{
		return_status = FALSE;
	}
	
	fgets(buffer,sizeof (buffer),pfinit);
	token = strtok(buffer,";");
	if(token != NULL)
	{
		strcpy(back_time_start,token);
	}else{
		return_status = FALSE;
	}
	
	fgets(buffer,sizeof (buffer),pfinit);
	token = strtok(buffer,";");
	if(token != NULL)
	{
		strcpy(my_lat,token);
	}else{
		return_status = FALSE;
	}
	

	fgets(buffer,sizeof (buffer),pfinit);
	token = strtok(buffer,";");
	if(token != NULL)
	{
		strcpy(my_long,token);
	}else{
		return_status = FALSE;
	}
	
	fgets(buffer,sizeof (buffer),pfinit);
	token = strtok(buffer,";");
	if(token != NULL)
	{
		strcpy(my_tz,token);
	}else{
		return_status = FALSE;
	}
	
	fgets(buffer,sizeof (buffer),pfinit);
	token = strtok(buffer,";");
	if(token != NULL)
	{
		strcpy(archive_dir,token);
	}else{
		return_status = FALSE;
	}
	
	fgets(buffer,sizeof (buffer),pfinit);
	token = strtok(buffer,";");
	if(token != NULL)
	{
		strcpy(use_power_calculations,token);
	}else{
		return_status = FALSE;
	}
	
	fgets(buffer,sizeof (buffer),pfinit);
	token = strtok(buffer,";");
	if(token != NULL)
	{
		cc_power_adjustment = abs(atof(token));
	}else{
		return_status = FALSE;
	}
	
	fclose(pfinit);

	return return_status;

}
	



//   Get the days to J2000
//   h is UT in decimal hours
//   FNday only works between 1901 to 2099 - see Meeus chapter 7

double FNday (int y, int m, int d, float h) {
long int luku = - 7 * (y + (m + 9)/12)/4 + 275*m/9 + d;
// type casting necessary on PC DOS and TClite to avoid overflow
luku+= (long int)y*367;
return (double)luku - 730531.5 + h/24.0;
};

//   the function below returns an angle in the range
//   0 to 2*pi

double FNrange (double x) {
    double b = 0.5*x / pi;
    double a = 2.0*pi * (b - (long)(b));
    if (a < 0) a = 2.0*pi + a;
    return a;
};

// Calculating the hourangle
//
double f0(double lat, double declin) {
double fo,dfo;
// Correction: different sign at S HS
dfo = rads*(0.5*SunDia + AirRefr); if (lat < 0.0) dfo = -dfo;
fo = tan(declin + dfo) * tan(lat*rads);
if (fo>0.99999) fo=1.0; // to avoid overflow //
fo = asin(fo) + pi/2.0;
return fo;
};

// Calculating the hourangle for twilight times
//
double f1(double lat, double declin) {
double fi,df1;
// Correction: different sign at S HS
df1 = rads * 6.0; if (lat < 0.0) df1 = -df1;
fi = tan(declin + df1) * tan(lat*rads);
if (fi>0.99999) fi=1.0; // to avoid overflow //
fi = asin(fi) + pi/2.0;
return fi;
};


//   Find the ecliptic longitude of the Sun

double FNsun (double d) {

//   mean longitude of the Sun

L = FNrange(280.461 * rads + .9856474 * rads * d);

//   mean anomaly of the Sun

g = FNrange(357.528 * rads + .9856003 * rads * d);

//   Ecliptic longitude of the Sun

return FNrange(L + 1.915 * rads * sin(g) + .02 * rads * sin(2 * g));
};




// Display decimal hours in hours and minutes
void showhrmn(double dhr,int *hour,int *minute) 
{

*hour =(int) dhr;
*minute = (int) ((dhr - (double) *hour)*60);
};



int sunrise_sunset(void){

double y,m,day,h,latit,longit;
double tzone,d,lambda;
double obliq,alpha,delta,LL,equation,ha,hb,twx;
double twam,altmax,noont,settm,riset,twpm;
time_t sekunnit;
struct tm *p;
time_t current_time;
struct tm *s_current_time;
int sunrise_minutes = 0;
int sunset_minutes = 0;
int current_minutes = 0;


degs = 180.0/pi;
rads = pi/180.0;
//  get the date and time from the user
// read system date and extract the year

/** First get time **/
time(&sekunnit);

/** Next get localtime **/

 p=localtime(&sekunnit);

 y = p->tm_year;
 // this is Y2K compliant method
 y+= 1900;
 m = p->tm_mon + 1;

 day = p->tm_mday;

 h = 12;


 latit = atof(my_lat); 
 longit = atof(my_long);
 tzone = atol(my_tz);

// testing
// m=6; day=10;


d = FNday((int)y, (int)m, (int)day, (float)h);

//   Use FNsun to find the ecliptic longitude of the
//   Sun

lambda = FNsun(d);

//   Obliquity of the ecliptic

obliq = 23.439 * rads - .0000004 * rads * d;

//   Find the RA and DEC of the Sun

alpha = atan2(cos(obliq) * sin(lambda), cos(lambda));
delta = asin(sin(obliq) * sin(lambda));

// Find the Equation of Time
// in minutes
// Correction suggested by David Smith
LL = L - alpha;
if (L < pi) LL += 2.0*pi;
equation = 1440.0 * (1.0 - LL / pi/2.0);
ha = f0(latit,delta);
hb = f1(latit,delta);
twx = hb - ha;	// length of twilight in radians
twx = 12.0*twx/pi;		// length of twilight in hours
/*printf("ha= %.2f   hb= %.2f \n",ha,hb);*/
// Conversion of angle to hours and minutes //
daylen = degs*ha/7.5;
     if (daylen<0.0001) {daylen = 0.0;}
// arctic winter     //

riset = 12.0 - 12.0 * ha/pi + tzone - longit/15.0 + equation/60.0;
settm = 12.0 + 12.0 * ha/pi + tzone - longit/15.0 + equation/60.0;
noont = riset + 12.0 * ha/pi;
altmax = 90.0 + delta * degs - latit; 
// Correction for S HS suggested by David Smith
// to express altitude as degrees from the N horizon
if (latit < delta * degs) altmax = 180.0 - altmax;

twam = riset - twx;	// morning twilight begin
twpm = settm + twx;	// evening twilight end

if (riset > 24.0) riset-= 24.0;
if (settm > 24.0) settm-= 24.0;

showhrmn(riset,&sunrise_hour,&sunrise_minute);
sunrise_minutes = (sunrise_hour * 60) + sunrise_minute;
showhrmn(settm,&sunset_hour,&sunset_minute);  
sunset_minutes = (sunset_hour * 60) + sunset_minute;

time(&current_time);
s_current_time =localtime(&current_time);
current_minutes = (s_current_time->tm_hour * 60) + s_current_time->tm_min;
if(current_minutes >= sunset_minutes || current_minutes <= sunrise_minutes)
{
	sundown = TRUE;
}else
{
	sundown = FALSE;
}

return 0;
}

	

double get_se_power(int year,int month,int day,int hour,int minute)
{

	FILE *se_fp; 
	char se_line_data[180];
	char start_date[] = "yyyymmdd";
	char se_file_name[MAX_PATH];
	size_t index;
	double power = 0;
	int power_found = 0;
	int date_found = 0;
	int time_found = 0;
	char se_date[80];
	char se_time[80];
	char se_power[80];
	char *se_data_token;

	
	sprintf(start_date,"%d%02d%02d",year,month,day);
	strcpy(se_file_name,se_input_path);
	index = strlen(se_file_name);
	sprintf(&se_file_name[index],"\\%s",plant_name);
	index = strlen(se_file_name);
	strcpy(&se_file_name[index],"-");
	index = strlen(se_file_name);
	strncpy(&se_file_name[index],start_date,sizeof(start_date));
	index = strlen(se_file_name);
	strcpy(&se_file_name[index],".csv");
	
	errno = 0;
	se_fp = fopen(se_file_name,"r");
	if (se_fp == NULL)
	{
		return FILE_NOT_FOUND;
	}
	sprintf(se_date,"%02d.%02d.%d",day,month,year);
	sprintf(se_time,"%02d:%02d:00",hour,minute);
	while((fgets(se_line_data,sizeof(se_line_data),se_fp)) != NULL)
	{
		if (power_found != POWER_FOUND)
		{
			se_data_token = strtok(se_line_data," ;");
			while(se_data_token != NULL)
			{
				if(time_found != TIME_FOUND)
				{
					if((strcmp(se_data_token,se_date)) == 0)
					{
						date_found = DATE_FOUND;
						while(se_data_token != NULL)
						{
							if(time_found != TIME_FOUND)
							{
								if((strcmp(se_data_token,se_time)) == 0)
									{
										time_found = TIME_FOUND;
										se_data_token = strtok(NULL," ;");
										se_data_token = strtok(NULL," ;");
										strcpy(se_power,se_data_token);
										power_found = POWER_FOUND;
									}
							}
						se_data_token = strtok(NULL," ;");
						}
					}
				}
			se_data_token = strtok(NULL," ;");
			}
		}
	}
	fclose(se_fp);

	if(date_found == FALSE)
	{
		power = DATE_NOT_FOUND;
	}else{
			if(time_found == FALSE)
				{
				power = TIME_NOT_FOUND;
				}else{
					if(power_found == FALSE)
					{
						power = POWER_NOT_FOUND;
					}else{
							power = atof(se_power);
							power = power * 1000;
						}
				}
		}
			
	return  power;
}


double get_cc_power(int year,int month,int day,int hour,int minute)
{

	FILE *cc_fp; 
	char cc_line_data[180];
	char start_date[] = "yyyymmdd";
	double power = 0;
	int power_found = 0;
	int date_found = 0;
	int time_found = 0;
	char cc_date[80];
	char cc_time[80];
	char cc_power[80];
	char *cc_data_token;

	errno = 0;
	cc_fp = fopen(cc_file_name,"r");
	if (cc_fp == NULL)
	{
		print_time();
		fprintf (fpLog,"Error opening CC File - %s - %s\n",cc_file_name,strerror(errno));
		fflush(fpLog);
		return FILE_NOT_FOUND;
	}
	
	sprintf(cc_date,"%02d.%02d.%d",day,month,year);
	sprintf(cc_time,"%02d:%02d:00",hour,minute);
	while((fgets(cc_line_data,sizeof(cc_line_data),cc_fp)) != NULL)
	{
		if (power_found != POWER_FOUND)
		{
			cc_data_token = strtok(cc_line_data," ;");
			while(cc_data_token != NULL)
			{
				if(time_found != TIME_FOUND)
				{
					if((strcmp(cc_data_token,cc_date)) == 0)
					{
						date_found = DATE_FOUND;
						while(cc_data_token != NULL)
						{
							if(time_found != TIME_FOUND)
							{
								if((strcmp(cc_data_token,cc_time)) == 0)
									{
										time_found = TIME_FOUND;
										cc_data_token = strtok(NULL," ;");
										cc_data_token = strtok(NULL," ;");
										strcpy(cc_power,cc_data_token);
										power_found = POWER_FOUND;
									}
							}
						cc_data_token = strtok(NULL," ;");
						}
					}
				}
			cc_data_token = strtok(NULL," ;");
			}
		}
	}
	fclose(cc_fp);

	if(date_found == FALSE)
	{
		power = DATE_NOT_FOUND;
	}else{
			if(time_found == FALSE)
				{
				power = TIME_NOT_FOUND;
				}else{
					if(power_found == FALSE)
					{
						power = POWER_NOT_FOUND;
					}else{
							power = atof(cc_power);
					}
				}
		}
			
	return power;
}

int send_update(int year,int month,int day,int hour,int minute,double power_used,double se_power,double cc_power,int formula)
{
	int status;
	int string_count;
	FILE *curl_fp;
	char curl_output[500];
	char update_date[80];
	char update_time[80];
	char curl_command[300];
	int curl_timeout = 5;
	
	sprintf(update_date,"%d%02d%02d",year,month,day);
	sprintf(update_time,"%02d:%02d",hour,minute);
	string_count = sprintf(curl_command,"curl -q -m %d -s -S --stderr - -d \"d=%s\" -d \"t=%s\" -d \"v2=%5.2f\" -d \"v4=%5.2f\" -d \"v7=%5.2f\" -d \"v8=%5.2f\" -d \"v9=%5.2f\" -d \"v10=%d\" -H \"X-Pvoutput-Apikey: %s\" -H \"X-Pvoutput-SystemId: %s\" http://pvoutput.org/service/r2/addstatus.jsp",
							curl_timeout,update_date,update_time,se_power,power_used,se_power,cc_power,power_used,formula,api_key,system_id);
	print_time();
	fprintf(fpLog,"Curl Command: %s\n",curl_command);
	fflush(fpLog);
	errno = 0;
	curl_fp = _popen(curl_command,"rt");
	if (curl_fp == NULL)
	{
		print_time();
		fprintf (fpLog,"New Process of Curl Failed %s\n",strerror(errno));
		fflush(fpLog);
		return NEW_PROCESS_FAILED;
	}
   	while (fgets(curl_output, 500, curl_fp) != NULL)
	{
		print_time();
		fprintf(fpLog,"%s", curl_output);
		fflush(fpLog);
	}
	fflush(fpLog);
	status = _pclose(curl_fp);
	
	return TRUE;
}

double calc_power_used(double se_power,double cc_power)
{
	double power_used = 0;
	int compare_status = 0;
	
	cc_power = cc_power * cc_power_adjustment;

	use_power_calculations[0] = toupper(use_power_calculations[0]);
	compare_status = strcmp(use_power_calculations,"N");
	if(compare_status == 0)
	{
		formula_used = FORMULA_RAW_CC_POWER;
		return cc_power;
	}

	/*if(cc_power > se_upper_limit_power)
	{
		if((cc_power - se_power) < standby_power)
		{
			power_used = cc_power + se_power;
		} else 
		{
			power_used = cc_power - se_power;
		}
		formula_used = FORMULA_CC_GREATER_THAN_UPPER_LIMIT;
		return power_used;
	}*/

	if(se_power == 0)
	{
		power_used = cc_power;
		formula_used = FORMULA_SE_POWER_0;
		return power_used;
	}

	if( (abs(se_power - cc_power)) < power_difference)
	{
		power_used = cc_power + se_power;
		if(power_used >= se_upper_limit_power)
		{
			power_used = cc_power;
		}
		formula_used = FORMULA_POWER_APPROX_EQUAL;
		return power_used;
	}

	if(cc_power > se_power)
	{
		power_used = cc_power + se_power;
		/*power_used = cc_power - se_power;
		if(power_used <= standby_power)
		{
			power_used = cc_power;
		}*/
		formula_used = FORMULA_CC_GREATER_THAN_SE;
		return power_used;
	}

	if(se_power > cc_power)
	{
		formula_used = FORMULA_SE_GREATER_THAN_CC_SUBTRACTIVE;
		power_used = se_power - cc_power;
		if(power_used < standby_power)
		{
			power_used = se_power + cc_power;
			formula_used = FORMULA_SE_GREATER_THAN_CC_ADAPTIVE;
		}
		
		
		return power_used;
	}

	formula_used = FORMULA_DEFAULT;
	power_used = cc_power;
	return power_used;
}





int get_power_values(int year,int month,int day,int hour,int minute,double *se_power,double *cc_power)
{
	int se_status = TRUE;
	int cc_status = TRUE;
	int return_status = TRUE;
		
	*se_power = get_se_power(year,month,day,hour,minute);
	if(*se_power < 0)
	{
		se_status = FALSE;
	}
	
	*cc_power = get_cc_power(year,month,day,hour,minute);
	if(*cc_power < 0)
	{
		cc_status = FALSE;
	}

	if(se_status == FALSE || cc_status == FALSE)
	{
		return_status = FALSE;
	}
	return return_status;
}

int main_routine(int year,int month,int day,int hour,int minute)
{
	double se_status = 0;
	double cc_status = 0;
	int status = 0;
	int send_status = 0;
	int power_status = 0;
	double power_used = 0;
	int switch_se_status = 0;
	int switch_cc_status = 0;
	
	power_status = get_power_values(year,month,day,hour,minute,&se_status,&cc_status);
	print_time();
	fprintf(fpLog,"SE STATUS: %5.2f TIME - %02d:%02d\n",se_status,hour,minute);
	print_time();
	fprintf(fpLog,"CC STATUS: %5.2f TIME - %02d:%02d\n",cc_status,hour,minute);
	fflush(fpLog);
	switch_se_status = (int) se_status;
	switch_cc_status = (int) cc_status;

	if(!power_status)
	{
		switch(switch_se_status)
		{
			case TIME_NOT_FOUND:
				se_status = 0;
				if(!sundown)
				{
					print_time();
					fprintf(fpLog,"SE Time Not Found: SE-Download is running behind. Check Status of SE-Download. ");
					fprintf(fpLog,"Setting SE Status to zero\n");
					fflush(fpLog);
				}else {
					print_time();
					fprintf(fpLog,"SE Time Not Found: OK, We are in Moon Light. Setting SE Status to zero\n");
					fflush(fpLog);
				}
				break;
			case FILE_NOT_FOUND:
				se_status = 0;
				if(!sundown)
				{
					print_time();
					fprintf(fpLog,"SE File Not Found. This should not happen. Setting SE Status to zero\n");
					fflush(fpLog);
				}else {
					print_time();
					fprintf(fpLog,"SE File Not Found. OK, We are in Moon Light. Setting SE Status to Zero\n");
					fflush(fpLog);
				}
				break;
			case DATE_NOT_FOUND:
				print_time();
				fprintf(fpLog,"SE DATE NOT FOUND in Current SE File. Something is really wacked! Exiting Program\n");
				fflush(fpLog);
				printf("FATAL ERROR - CHECK LOG FILE - PROGRAM TERMINATED\n");
				exit(FALSE);
				break;
			default:
				print_time();
				if(se_status >= 0)
				{
					fprintf(fpLog,"SE File Read Success.\n");
				}else
				{
					fprintf(fpLog,"SE File Read Failure.  Undefined Error\n");
					fprintf(fpLog,"Setting SE Status to Zero\n");
					se_status = 0;
				}
				fflush(fpLog);
		}

		switch(switch_cc_status)
		{
			case TIME_NOT_FOUND:
				cc_status = standby_power;
				print_time();
				fprintf(fpLog,"CC Time Not Found: CCTERM is running behind. Check Status of CCTERM. ");
				fprintf(fpLog,"Setting CC Status to Standby Power\n");
				fflush(fpLog);
				break;
			case FILE_NOT_FOUND:
				cc_status = standby_power;
				print_time();
				fprintf(fpLog,"CC File Not Found. This should not happen. Check Status of CCTERM. ");
				fprintf(fpLog,"Setting CC Status to Standby Power\n");
				fflush(fpLog);
				break;
			case DATE_NOT_FOUND:
				cc_status = standby_power;
				print_time();
				fprintf(fpLog,"CC Date Not Found: CCTERM is running behind. Check Status of CCTERM. ");
				fprintf(fpLog,"Setting CC Status to Standby Power\n");
				fflush(fpLog);
				break;
			default:
				print_time();
				if(cc_status >= 0){
					fprintf(fpLog,"CC File Read Success.\n");
				}else {
					fprintf(fpLog,"CC File Read Failure.  Undefined Error. ");
					fprintf(fpLog,"Setting CC Status to Standby Power\n");
					cc_status = standby_power;
				}
				fflush(fpLog);
		}
	}
	power_used = calc_power_used(se_status,cc_status);
	print_time();
	fprintf(fpLog,"Formula Number: %d %s  Power Values: SE Power: %5.2f  CC Power: %5.2f Power Used: %5.2f\n",
				formula_used,formula_list[formula_used],se_status,cc_status,power_used);
	fflush(fpLog);
	send_status = send_update(year,month,day,hour,minute,power_used,se_status,cc_status,formula_used);
			
	return status;
}

int get_back_date(int *year,int *month,int *day,int *hour,int *minute)
{
	char *data_token;
	int compare_status = 0;
	
    back_date[0] = toupper(back_date[0]);
	compare_status = strcmp(back_date,"Y");
	if(compare_status == 0){
		data_token = strtok(back_date_start,".");
		if(data_token != NULL){
			*day = atoi(data_token);
		}
		data_token = strtok(NULL,".");
		if(data_token != NULL){
			*month = atoi(data_token);
		}
		data_token = strtok(NULL,".");
		if(data_token != NULL){
			*year = atoi(data_token);
		}
		data_token = strtok(back_time_start,":");
		if(data_token != NULL){
			*hour = atoi(data_token);
		}
		data_token = strtok(NULL,":");
		if(data_token != NULL){
			*minute = atoi(data_token);
		}
		return TRUE;
	}
	return FALSE;
}

int _tmain(int argc, _TCHAR* argv[])
{
	int se_status = 0;
	int cc_status = 0;
	int status;
	time_t tim;
	time_t tim_five_minutes;
	struct tm *now;
	struct tm *five_minute_mark;
	struct tm *back_date;
	time_t back_time;
	int on_the_fives = 0;
	int year = 1900;
	int month = 1;
	int day = 1;
	int hour = 0;
	int minute = 0;
		
	printf("\nProgram is starting\n");	
	fpLog = fopen("pvccupload-log.txt", "a");
	if (fpLog == NULL) 
	{
		printf("Can't Open Logfile\n");
		exit(1);
	}
	init_formula_list();
	status = init_params();
	if (status == FALSE)
	{
		fprintf(fpLog,"Program Initialization Failed: Program TERMINATED\n");
		exit(FALSE);
	}
	fprintf(fpLog,"\n\n");
	print_time();
	fprintf(fpLog,"Program is starting. Program is Initialized\n");	
	fflush(fpLog);
	status = sunrise_sunset();
	
	/* Start the recovery routine*/
	if(status = get_back_date(&year,&month,&day,&hour,&minute)){
		if(minute%5 != 0){
			do{
				minute = minute + 1;
			}while (minute%5 != 0);
		}
		back_time = time(NULL);
		back_date = localtime(&back_time);
		back_date->tm_year = year - 1900;
		back_date->tm_mon = month - 1;
		back_date->tm_mday = day;
		back_date->tm_hour = hour;
		back_date->tm_min = minute;
		back_date->tm_sec = 0;
		back_time = mktime(back_date);
		back_date = localtime(&back_time);
		time(&tim);
		now = localtime(&tim);
		fprintf(fpLog,"\n");
		print_time();
		fprintf(fpLog,"Running Recovery Routine\n");
		fflush(fpLog);
		back_date = localtime(&back_time);
		if(back_time < tim){
			do{
				/*time(&tim);
				now = localtime(&tim);*/
				fprintf(fpLog,"\n\npvccupload time - In Recovery Mode\n");
				status = main_routine((back_date->tm_year + 1900),(back_date->tm_mon + 1),back_date->tm_mday,back_date->tm_hour,back_date->tm_min);
				back_time = back_time + (5 * 60);
				back_date = localtime(&back_time);
				tim = time(NULL);
				fflush(fpLog);
				Sleep(20000);
				} while (back_time < tim);
		}else{
			print_time();
			fprintf(fpLog,"Recovery Time Can Not be in the Future.  Check the INIT File settings\n");
		}
		fprintf(fpLog,"\n");
		print_time();
		fprintf(fpLog,"Finished Recovery Routine\n");
		fflush(fpLog);
	}
	/* End of Recovery Routine*/

	/* Start of Main Loop*/	
	while(1)
	{
		status = sunrise_sunset();
		tim=time(NULL);
		five_minute_mark=localtime(&tim);
		status = sunrise_sunset();
		if(five_minute_mark->tm_min%5 == 0)
		{
			on_the_fives = five_minute_mark->tm_min;
			tim_five_minutes = tim;
			do
			{
				Sleep(10000);
				tim=time(NULL);
				five_minute_mark=localtime(&tim);
			} while (on_the_fives == five_minute_mark->tm_min); /*Wait until the next minute to allow CC and SE data to be recorded*/
			Sleep(60000);										/*Wait 1 minute.  Give PVUPLOAD time to complete */
			tim = time(NULL);
			now = localtime(&tim);
			fprintf(fpLog,"\n\n");
			print_time();
			fprintf(fpLog,"Update to PVOUTPUT.ORG - Started\n");
			fflush(fpLog);
			tim_five_minutes = tim_five_minutes - (5 * 60);  /*Go back in time 5 minutes */
			five_minute_mark = localtime(&tim_five_minutes);
			year = five_minute_mark->tm_year + 1900;
			month = five_minute_mark->tm_mon + 1;
			status = main_routine(year,month,five_minute_mark->tm_mday,five_minute_mark->tm_hour,five_minute_mark->tm_min);
			fprintf(fpLog,"\n");
			print_time();
			fprintf(fpLog,"Update to PVOUTPUT.ORG - Ended\n");
			fflush(fpLog);
		}
		Sleep(10000);
	} /*end - while(1)*/
	/* End of of Main Loop */
	
	return 0;
}


